package com.chenyue.cm.api.goods;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.chenyue.cm.account.domain.JdAccount;
import com.chenyue.cm.account.domain.JdAccountRecord;
import com.chenyue.cm.account.domain.JdIntegralRecord;
import com.chenyue.cm.account.service.JdAccountService;
import com.chenyue.cm.auth.Login;
import com.chenyue.cm.auth.LoginUser;
import com.chenyue.cm.bean.Success;
import com.chenyue.cm.common.constant.Constants;
import com.chenyue.cm.common.domain.JdAboutUs;
import com.chenyue.cm.common.service.JdAboutUsService;
import com.chenyue.cm.common.utils.StringUtil;
import com.chenyue.cm.common.utils.StringUtils;
import com.chenyue.cm.common.vo.Page;
import com.chenyue.cm.match.dao.PublicAreaMapper;
import com.chenyue.cm.match.domain.PublicArea;
import com.chenyue.cm.user.dao.JdGoodsSkuMapper;
import com.chenyue.cm.user.domain.*;
import com.chenyue.cm.user.domain.vo.GoodsJSVo;
import com.chenyue.cm.user.service.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.*;
import org.apache.commons.lang.math.NumberRange;
import org.bouncycastle.jce.provider.symmetric.AES;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/member")
@Api(value = "购物车相关", tags = "购物车相关")
public class ApiShopingCartController {
    @Resource
    private JdAppUserService appUserService;
    @Resource
    private JdGoodsSpuService goodsSpuService;
    @Resource
    private JdGoodsSkuService goodsSkuService;
    @Resource
    private JdGoodsSkuMapper goodsSkuMapper;
    @Resource
    private JdMemberShoppingCartService memberShoppingCartService;
    @Resource
    private JdOrderInfoService orderInfoService;
    @Resource
    private JdMemberAddressService addressService;
    @Resource
    private PublicAreaMapper areaMapper;
    @Resource
    private JdAccountService accountService;


    /**
     * 个人中心--加入购物车
     * 【P1003】
     *
     * @param request
     * @param response
     * @return
     */
    @Login
    @PostMapping("/addShoppingCart")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "商品id", name = "goodsId", dataType = "string", required = true),
            @ApiImplicitParam(value = "规格", name = "skuId", dataType = "string"),
            @ApiImplicitParam(value = "数量", name = "selectedNum", dataType = "string", required = true),
    })
    @ApiOperation(value = "加入购物车", notes = "加入购物车")
    public Success<String> addShoppingCart(@ApiIgnore @LoginUser JdAppUser user,HttpServletRequest request, HttpServletResponse response) {
        if(user == null){
            return Success.error();
        }
        String goodsId = request.getParameter("goodsId");
        String skuId = request.getParameter("skuId");
        String selectedNum = request.getParameter("selectedNum");
        if (StringUtils.isEmpty(user.getId().toString())
                || StringUtils.isEmpty(goodsId)
                || StringUtils.isEmpty(selectedNum)) {
            return Success.error("参数不能为空");
        }
        JdGoodsSpu spu = goodsSpuService.selectByPrimaryKey(goodsId);
        if (spu.getState() == 0) {
            return Success.error("商品已下架，请重新购买");
        }
        //添加购物车
        return memberShoppingCartService.addCart(user.getId().toString(), goodsId, skuId, selectedNum);
    }

    @Login
    @PostMapping("/getShoppingCartList")
    @ResponseBody
    @ApiOperation(value = "个人中心--用户购物车列表", notes = "个人中心--用户购物车列表")
    @ApiOperationSupport(order = 4)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "当前页", name = "page", dataType = "int", required = true),
            @ApiImplicitParam(value = "条数", name = "rows", dataType = "int", required = true),
    })
    public Success<Page<List<JdMemberShoppingCart>>> getShoppingCartList(@ApiIgnore @LoginUser JdAppUser user,HttpServletRequest request,
                                                                         @RequestParam(defaultValue = "1") Integer page,
                                                                         @RequestParam(defaultValue = "10") Integer rows) {

        if(user == null){
            return Success.error();
        }
        LambdaQueryWrapper<JdMemberShoppingCart> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(JdMemberShoppingCart::getMemberId, user.getId());
        wrapper.orderByDesc(JdMemberShoppingCart::getCreateTime);
        final int total = memberShoppingCartService.count(wrapper);
        final Page<List<JdMemberShoppingCart>> result = new Page<>(page, rows, total);
        wrapper.last(result.convertPage());
        final List<JdMemberShoppingCart> list = memberShoppingCartService.list(wrapper);
        for (JdMemberShoppingCart cart : list) {
            JdGoodsSpu spu = goodsSpuService.getById(cart.getGoodsId());
            if (spu == null||spu.getState() == 0) {
                continue;
            }
            cart.setGoodsId(spu.getId());
            LambdaQueryWrapper<JdGoodsSku> w = new LambdaQueryWrapper<>();
            w.eq(JdGoodsSku::getGoodsId, spu.getId());
            if (cart.getSkuId() != null) {
                w.eq(JdGoodsSku::getId, cart.getSkuId());
            }
            JdGoodsSku sku = goodsSkuService.getOne(w);

            if (sku == null || sku.getSkuStock() == 0 || spu.getState().equals(Constants.COMMON_STATE_0)) {
                memberShoppingCartService.removeById(cart.getId());
            } else if (sku.getSkuStock() < cart.getPurchaseNum()) {
                cart.setPurchaseNum(sku.getSkuStock());
            }
        }
        result.setContent(list);
        return Success.success(result);
    }
    
    
    /**
     * 结算
     * 【P1003】
     *
     * @param request
     * @param response
     * @return
     */
    @Login
    @PostMapping("/goodsSettlement")
    @ResponseBody
    @ApiOperation(value = "结算", notes = "结算")
    @ApiOperationSupport(order = 4)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "购物车id(多个)", name = "cartIds", dataType = "string"),
            @ApiImplicitParam(value = "商品id（单商品）", name = "goodsId", dataType = "string"),
            @ApiImplicitParam(value = "数量（单商品）", name = "selectedNum", dataType = "string"),
            @ApiImplicitParam(value = "规格id", name = "skuId", dataType = "string"),
            @ApiImplicitParam(value = "优惠券id", name = "couponId", dataType = "string"),
    })
    public Success<GoodsJSVo> goodsSettlement(@ApiIgnore @LoginUser JdAppUser user,HttpServletRequest request, HttpServletResponse response) {
        //根据token获取用户id
        if(user == null){
            return Success.error();
        }
        String skuId = request.getParameter("skuId");
        String goodsId = request.getParameter("goodsId");
        String selectedNum = request.getParameter("selectedNum");
        GoodsJSVo vo;
        if (StringUtils.isNotEmpty(goodsId) && StringUtils.isNotEmpty(selectedNum)) {
            JdGoodsSku sku;
            if (StringUtils.isNotEmpty(skuId) && !skuId.equals("undefined")) {
                sku = goodsSkuMapper.selectById(skuId);
            } else {
                sku = new JdGoodsSku();
                sku.setGoodsId(goodsId);
                sku = goodsSkuMapper.selectById(sku);
            }
            if (sku.getSkuStock() < Integer.parseInt(selectedNum)) {
                return Success.error("库存不足");
            }
            vo = orderInfoService.createOrder(request);
        } else {
            Success r = orderInfoService.createShoppingOrder(request);
            if (r.getCode() == 0) {
                ObjectMapper objectMapper = new ObjectMapper();
                vo = objectMapper.convertValue(r.getResult(), GoodsJSVo.class);
            } else {
                return Success.error("该商品已售完");
            }
        }
        return Success.success(vo);
    }

    /**
     * 个人中心--修改购物车单品数量
     * 【P1003】
     *
     * @param request
     * @param response
     * @return
     */
    @Login
    @PostMapping("/changeCartNumById")
    @ResponseBody
    @ApiOperation(value = "个人中心--修改购物车单品数量", notes = "个人中心--修改购物车单品数量")
    @ApiOperationSupport(order = 5)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "token标识", name = "token", dataType = "string"),
            @ApiImplicitParam(value = "购物车id", name = "id", dataType = "string"),
            @ApiImplicitParam(value = "数量", name = "num", dataType = "string"),
    })
    public Success changeCartNumById(@ApiIgnore @LoginUser JdAppUser user,HttpServletRequest request, HttpServletResponse response) {
        if(user == null){
            return Success.error();
        }
        String cartId = request.getParameter("id");
        String num = request.getParameter("num");
        JdMemberShoppingCart a = memberShoppingCartService.selectByPrimaryKey(cartId);
        if (a == null) {
            return Success.error("该商品不在购物车内");
        } else {
            JdGoodsSku sku = goodsSkuService.getById(a.getSkuId());
            if (sku.getSkuStock() < Integer.parseInt(num)) {
                return Success.error(a.toString());
            }
            a.setPurchaseNum(Integer.valueOf(num));
            memberShoppingCartService.updateById(a);
            return Success.success(a);
        }
    }

    /**
     * 个人中心--删除购物车单品信息
     * 【P1003】
     *
     * @param request
     * @param response
     * @return
     */
    @Login
    @PostMapping("/deleteShoppingCartById")
    @ResponseBody
    @ApiOperation(value = "个人中心--删除购物车单品信息", notes = "个人中心--删除购物车单品信息")
    @ApiOperationSupport(order = 4)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "购车id(多个)", name = "cartIds", dataType = "string", required = true)
    })
    public Success deleteShoppingCartById(@ApiIgnore @LoginUser JdAppUser user,HttpServletRequest request, HttpServletResponse response) {
        JdAppUser appUser = appUserService.getAppUserByToken(request.getParameter("token"));
        if(appUser == null){
            return Success.error();
        }
        String cartIds = request.getParameter("cartIds");
        String[] ids = cartIds.split(",");
        for (String id : ids) {
            JdMemberShoppingCart cart = memberShoppingCartService.selectByPrimaryKey(id);
            if (cart == null) {
                continue;
            }
            memberShoppingCartService.deleteByPrimaryKey(id);
        }
        return Success.success();
    }

    /**
     * 个人中心--统计购物车商品数量
     * 【P1003】
     *
     * @return
     */
    @Login
    @PostMapping("/countCartGoodsNum")
    @ResponseBody
    @ApiOperation(value = "个人中心--统计购物车商品数量", notes = "个人中心--统计购物车商品数量")
    @ApiOperationSupport(order = 4)
    public Success countCartGoodsNum(@ApiIgnore @LoginUser JdAppUser user) {
        if(user == null){
            return Success.error();
        }
        //搜索用户购物车商品数量
        int count = 0;
        LambdaQueryWrapper<JdMemberShoppingCart> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(JdMemberShoppingCart::getMemberId, user.getId());
        List<JdMemberShoppingCart> carts = memberShoppingCartService.list(wrapper);
        if (carts.size() > 0) {
            for (JdMemberShoppingCart cart : carts) {
                count = count + cart.getPurchaseNum();
            }
        }
        return Success.success(count);
    }

//
    @Login
    @PostMapping("/listUserAddress")
    @ApiOperation(value = "个人中心---获取用户地址列表",notes = "个人中心---获取用户地址列表")
    @ApiOperationSupport(order = 5)
    public Success<List<JdMemberAddress>> saveUserAddressw(@ApiIgnore @LoginUser JdAppUser user){
        List<JdMemberAddress> jdMemberAddresses;
        if (user == null) {
            return Success.error();
        }
        jdMemberAddresses = addressService.lambdaQuery()
                .eq(JdMemberAddress::getMemberId, user.getId()).list();
        return Success.success(jdMemberAddresses);
    }

    /**
     * 保存用户地址
     * @return
     */
    @Login
    @PostMapping("/address/saveUserAddress")
    @ApiOperation(value="保存用户地址",notes="保存用户地址")
    @ApiOperationSupport(order=6)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "收件人姓名", name = "buyerName", dataType = "string"),
            @ApiImplicitParam(value = "收件人手机号", name = "buyerPhone", dataType = "string"),
            @ApiImplicitParam(value = "所属省份", name = "provinceName", dataType = "string"),
            @ApiImplicitParam(value = "所属城市", name = "cityName", dataType = "string"),
            @ApiImplicitParam(value = "所属区域", name = "areaName", dataType = "string"),
            @ApiImplicitParam(value = "详细地址", name = "addressDetail", dataType = "string"),
            @ApiImplicitParam(value = "备注", name = "remark", dataType = "string"),
            @ApiImplicitParam(value = "默认地址(0否 1是)", name = "number", dataType = "integer")
    })
    public Success<Object> saveUserAddress(@ApiIgnore @LoginUser JdAppUser user, String buyerName,
                                           String buyerPhone,String provinceName, String  cityName,
                                           String areaName, String addressDetail, String remark, String number) {
        try {
            if(user == null){
                return Success.error();
            }
            JdMemberAddress jdMemberAddress = new JdMemberAddress();
            jdMemberAddress.setMemberId(user.getId().toString());
            jdMemberAddress.setBuyerName(buyerName);
            jdMemberAddress.setBuyerPhone(buyerPhone);
            jdMemberAddress.setProvinceName(provinceName);
            jdMemberAddress.setCityName(cityName);
            jdMemberAddress.setAreaName(areaName);
            Integer province = areaMapper.selectOne(Wrappers.<PublicArea>lambdaQuery().eq(PublicArea::getName, provinceName)).getId();
            Integer city = areaMapper.selectOne(Wrappers.<PublicArea>lambdaQuery().eq(PublicArea::getName, cityName)).getId();
            Integer area = areaMapper.selectOne(Wrappers.<PublicArea>lambdaQuery().eq(PublicArea::getName, areaName)).getId();
            jdMemberAddress.setProvinceCode(province);
            jdMemberAddress.setCityCode(city);
            jdMemberAddress.setAreaCode(area);
            jdMemberAddress.setAddressDetail(addressDetail);
            jdMemberAddress.setRemark(remark);
            if (number.equals("1")){
                jdMemberAddress.setDefaultFlag(number);
                List<JdMemberAddress> list = addressService.list(Wrappers.<JdMemberAddress>lambdaQuery().eq(JdMemberAddress::getMemberId, user.getId()).eq(JdMemberAddress::getDefaultFlag, 1));
                if (list.size()>0){
                    for(JdMemberAddress address : list) {
                        address.setDefaultFlag("0");
                        addressService.updateById(address);
                    }
                }
            }
            addressService.save(jdMemberAddress);
            return Success.success();
        } catch (Exception e) {
            e.printStackTrace();
            return Success.error();
        }
    }


    /**
     * 保存用户地址
     * @return
     */
    @Login
    @PostMapping("/address/updateUserAddress")
    @ResponseBody
    @ApiOperation(value="修改用户地址",notes="修改用户地址")
    @ApiOperationSupport(order=6)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "主键ID",name = "id",dataType = "String"),
            @ApiImplicitParam(value = "收件人姓名", name = "buyerName", dataType = "string"),
            @ApiImplicitParam(value = "收件人手机号", name = "buyerPhone", dataType = "string"),
            @ApiImplicitParam(value = "所属省份", name = "provinceName", dataType = "string"),
            @ApiImplicitParam(value = "所属城市", name = "cityName", dataType = "string"),
            @ApiImplicitParam(value = "所属区域", name = "areaName", dataType = "string"),
            @ApiImplicitParam(value = "详细地址", name = "addressDetail", dataType = "string"),
            @ApiImplicitParam(value = "备注", name = "remark", dataType = "string"),
            @ApiImplicitParam(value = "默认地址(0否 1是)", name = "number", dataType = "integer")
    })
    public Success<Object> updateUserAddress(@ApiIgnore @LoginUser JdAppUser user, String id,
                                             String buyerName,String buyerPhone,String provinceName, String  cityName,
                                             String areaName, String addressDetail, String remark, String number) {
        try {
            if(user == null){
                return Success.error();
            }
            JdMemberAddress jdMemberAddress = new JdMemberAddress();
            jdMemberAddress.setId(id);
            jdMemberAddress.setMemberId(user.getId().toString());
            jdMemberAddress.setBuyerName(buyerName);
            jdMemberAddress.setBuyerPhone(buyerPhone);
            jdMemberAddress.setProvinceName(provinceName);
            jdMemberAddress.setCityName(cityName);
            jdMemberAddress.setAreaName(areaName);
            Integer province = areaMapper.selectOne(Wrappers.<PublicArea>lambdaQuery().eq(PublicArea::getName, provinceName)).getId();
            Integer city = areaMapper.selectOne(Wrappers.<PublicArea>lambdaQuery().eq(PublicArea::getName, cityName)).getId();
            Integer area = areaMapper.selectOne(Wrappers.<PublicArea>lambdaQuery().eq(PublicArea::getName, areaName)).getId();
            jdMemberAddress.setProvinceCode(province);
            jdMemberAddress.setCityCode(city);
            jdMemberAddress.setAreaCode(area);
            jdMemberAddress.setAddressDetail(addressDetail);
            jdMemberAddress.setRemark(remark);
            if (number.equals("1")){
                jdMemberAddress.setDefaultFlag(number);
                List<JdMemberAddress> list = addressService.list(Wrappers.<JdMemberAddress>lambdaQuery().eq(JdMemberAddress::getMemberId, user.getId()).eq(JdMemberAddress::getDefaultFlag, 1));
                if (list.size()>0){
                    for(JdMemberAddress address : list) {
                        address.setDefaultFlag("0");
                        addressService.updateById(address);
                    }
                }
            }
            addressService.updateById(jdMemberAddress);
            return Success.success();
        } catch (Exception e) {
            e.printStackTrace();
            return Success.error();
        }
    }


    /**
     * 删除用户地址
     * @param userAddress
     * @return
     */
    @Login
    @PostMapping("/address/deleteUserAddress")
    @ResponseBody
    @ApiOperation(value="删除用户地址",notes="删除用户地址")
    @ApiOperationSupport(order=8)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "地址ID", name = "id", dataType = "integer")
    })
    public Success<Object> deleteUserAddress(@ApiIgnore @LoginUser JdAppUser user,String id) {
        try {
            if(user == null){
                return Success.error();
            }
            addressService.removeById(id);
            return Success.success();
        } catch (Exception e) {
            return Success.error();
        }
    }


    //个人中心---积分
    @Login
    @PostMapping("/address/getIntegral")
    @ResponseBody
    @ApiOperation(value="当前积分",notes="当前积分")
    @ApiOperationSupport(order=9)

    public Success<Integer> getIntegral(@ApiIgnore @LoginUser JdAppUser user) {
        if (user == null) {
            return Success.error();
        }
        Integer integral = accountService.getOne(Wrappers.<JdAccount>lambdaQuery().eq(JdAccount::getUserId, user.getId())).getIntegral();
        if (integral == null) {
            integral = 0;
        }
        return Success.success(integral);
    }


    /**
     * 删除用户地址
     * @param userAddress
     * @return
     */
    @Login
    @PostMapping("/address/getIntegralList")
    @ResponseBody
    @ApiOperation(value="积分列表",notes="积分列表")
    @ApiOperationSupport(order=8)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "类型(0全部,1收入,2支出)", name = "type", dataType = "integer")
    })
    public Success<List<JdIntegralRecord>> getIntegralList(@ApiIgnore @LoginUser JdAppUser user,Integer type) {
        try {
            if(user == null){
                return Success.error();
            }
            List<JdIntegralRecord> records = accountService.selectByType(user,type);
            return Success.success(records);
        } catch (Exception e) {
            return Success.error();
        }
    }

}
